package server

import (
	"tcp_server/conf"
	. "tcp_server/protocol"
	"time"
)

// 直接发送消息
func SendMessage(userId string, data []byte) int {
	if conn, ok := ClientConnection.Load(userId); ok {
		client := conn.(*ClientConn)
		if err := client.WriteDecrypt(data); err != nil {
			client.LogError("write data failed")
			client.Close()
			client.StopChan <- true
			return conf.CONN_ERR_WRITE
		}
		return conf.SUCCESS
	} else {
		return conf.CONN_NOT_EXIT
	}
}

// 广播发送消息
func SendAllUserMessage(data []byte) {
	ClientConnection.Range(func(key, value interface{}) bool {
		client := value.(*ClientConn)
		if err := client.WriteDecrypt(data); err != nil {
			client.LogError("write data failed")
			client.Close()
			client.StopChan <- true
		}
		return true
	})
}

func writeDataTest(conn *ClientConn) {
	ticker := time.NewTicker(3 * time.Second)
	for {
		<-ticker.C
		err := conn.WriteDecrypt([]byte("认证成功，这里可以发送业务数据了。服务器下发业务数据给" + conn.UserId))
		if err != nil {
			conn.LogError("write data failed", err)
			break
		}
	}
	conn.Close()
}

/*---------------------信道能够保证并发write下消息串行发送，但是发现go的write底层有加锁操作----------------------*/
// 往写信道发送消息
/**
 * @Description: 往写信道发送消息。信道能够保证并发write下消息串行发送，缺点就是不能即使知道发送的消息write出错
 * 后来发现go的TcpConn的write底层有加锁操作，所以是线程安全的，就不使用信道了
 */
func SendChanMessage(userId string, data []byte) int {
	if conn, ok := ClientConnection.Load(userId); ok {
		client := conn.(*ClientConn)
		client.WriteChan <- data
		return conf.SUCCESS
	} else {
		return conf.CONN_NOT_EXIT
	}
}

// 处理发送信道消息的协程
func SendMessageThread(conn *ClientConn) {
	for {
		data := <-conn.WriteChan
		err := conn.WriteDecrypt(data)
		if err != nil {
			conn.LogError("write data failed")
			conn.Close()
			conn.StopChan <- true
			break
		}
	}
}
